package configuration

import (
	"encoding/json"
	"fmt"
	"kop/modules/configuration/client"
	serverC "kop/modules/server/client"
	"kop/pb/service"
	"kop/util/log"
	"sync"
	"time"
)

func init() {

	var data []ActivityConf
	if err := json.Unmarshal(client.Load("ActivityTemplate"), &data); err != nil {
		panic(err)
	}

	for _, v := range data {

		switch v.Type {
		case TypePay:
			if v.BeginType == 1 {
				payList1 = append(payList1, v)
			} else {
				payList2 = append(payList2, v)
			}
		case TypeQuest:
			if v.BeginType == 1 {
				questList1 = append(questList1, v)
			} else {
				questList2 = append(questList2, v)
			}
		case TypeRanking:
			if v.BeginType == 1 {
				rankingList1 = append(rankingList1, v)
			} else {
				rankingList2 = append(rankingList2, v)
			}
		case TypeTreasure:
			if v.BeginType == 1 {
				treasureList1 = append(treasureList1, v)
			} else {
				treasureList2 = append(treasureList2, v)
			}
		case TypeGuildRanking:
			if v.BeginType == 1 {
				公会榜1 = append(公会榜1, v)
			} else {
				公会榜2 = append(公会榜2, v)
			}
		}
	}

	log.Info("Load ActivityTemplate.json success.")

	//------------------------------------------------------------------------------------------------------

	res, err := serverC.GetServers()
	if err != nil {
		panic(err)
	}

	for _, v := range res {
		servers[v.ServerID] = v
	}

}

const (
	Z8 = 28 // 开服28天

	TypeQuest        aType = 3  // 限时活动
	TypePay          aType = 5  // 充值活动
	TypeTreasure     aType = 8  // 寻宝活动
	TypeRanking      aType = 9  // 排名活动
	TypeGuildRanking aType = 10 // 公会排名活动
)

type (
	aType int8

	// 活动
	ActivityConf struct {
		ActivityID int32  `json:"ID"` // 活动ID
		Name       string // 活动名称
		Type       aType  // 活动类型
		SubType    int32  // 子类型
		BeginType  uint8  // 1 开服X天 2循环
		BeginDay   int    // 开始天数
		EndDay     int    // 结算天数
		ShopID     int32  // 商店ID2
		bTime      time.Time
		eTime      time.Time
	}

	ActivityValueConf struct {
		ID         int32  // 任务ID
		ActivityID int32  // 活动ID
		Name       string // 任务名称
		Type       int32  // 条件类型
		Value      int64  //
		AwardID    int32  // 奖励ID
	}

	ActivityList []ActivityConf
	//ActivityValueList []ActivityValueConf
)

func (c ActivityConf) BeginTime() time.Time {

	return c.bTime
}

func (c ActivityConf) EndTime() time.Time {

	return c.eTime
}

// 活动结束后多加一天的展示时间
func (c ActivityConf) ShowDay() int {
	return c.EndDay + 1
}

// 是否正常活动期间
func (c ActivityConf) InTime() bool {

	return time.Now().Sub(c.EndTime()) <= 0
}

func (c *ActivityConf) setTime1(serverID int32) {

	var n = 开服第N天(serverID)

	var year, month, day = time.Now().Date()
	var t = time.Date(year, month, day, 0, 0, 0, 0, time.Local)

	c.bTime = t.Add(time.Duration(-(n - c.BeginDay)) * time.Hour * 24)
	c.eTime = t.Add(time.Hour*22 + time.Duration(c.EndDay-n)*time.Hour*24)
}

func (c *ActivityConf) setTime2(serverID int32) {

	var n = 开服第N天(serverID) // 开服第X天
	n -= Z8

	if n <= 0 {
		panic("(c *ActivityConf) setTime2: n <= 0")
	}

	var mod = n % Z8
	if mod == 0 {
		mod = Z8
	}

	var year, month, day = time.Now().Date()
	var t = time.Date(year, month, day, 0, 0, 0, 0, time.Local)

	c.bTime = t.Add(time.Duration(-(mod - c.BeginDay)) * time.Hour * 24)
	c.eTime = t.Add(time.Hour*22 + time.Duration(c.EndDay-mod)*time.Hour*24)
}

func (c ActivityConf) List() (res []ActivityValueConf) {

	var configs []ActivityValueConf
	switch c.Type {
	case TypeQuest:
		configs = questConfigs
	case TypePay:
		configs = payConfigs
	}
	for _, v := range configs {
		if v.ActivityID == c.ActivityID {
			res = append(res, v)
		}
	}

	//sort.Sort(res)
	return res
}

// 开服28天内的
func (c ActivityList) GetOne1(serverID int32) (ActivityConf, bool) {

	var n = 开服第N天(serverID) // 开服第X天

	if n <= Z8 {
		// open server not over 28 day
		for _, v := range c {
			if n <= v.EndDay {
				//v.ServerID = serverID
				v.setTime1(serverID)
				return v, true
			}
		}
	}

	return ActivityConf{}, false
}

// 开服28天后的
func (c ActivityList) GetOne2(serverID int32) ActivityConf {

	var n = 开服第N天(serverID) // 开服第X天
	n -= Z8

	var endDay = c[len(c)-1].EndDay
	var mod = n % endDay
	if mod == 0 {
		mod = endDay
	}
	for _, v := range c {
		if mod <= v.EndDay {
			v.setTime2(serverID)
			//v.ServerID = serverID
			return v
		}
	}

	panic(fmt.Sprintf("activity [%d] configs err", c[0].Type))
}

var (
	lock    sync.Mutex
	servers = make(map[int32]*service.Server)

	payList1 ActivityList // 开服X日的
	payList2 ActivityList // 循环的

	questList1 ActivityList // 开服X日的
	questList2 ActivityList // 循环的

	treasureList1 ActivityList // 开服X日的
	treasureList2 ActivityList // 循环的

	rankingList1 []ActivityConf // 开服X日的
	rankingList2 []ActivityConf // 循环的

	公会榜1 []ActivityConf // 开服X日的
	公会榜2 []ActivityConf // 循环的

)

func 开服时间(serverID int32) time.Time {

	if server, ok := servers[serverID]; ok {

		var year, month, day = time.Unix(server.Timestamp.Seconds, 0).Date()
		return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
	}

	lock.Lock()
	lock.Unlock()

	var res, _ = serverC.GetServers()
	for _, v := range res {
		servers[v.ServerID] = v
		if v.ServerID == serverID {

			var year, month, day = time.Unix(v.Timestamp.Seconds, 0).Date()
			return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
		}
	}

	panic(fmt.Errorf("server[%d] not found", serverID))
}

func 开服第N天(serverID int32) int {

	return int(time.Now().Sub(开服时间(serverID)).Hours())/24 + 1
}
